﻿using System.Diagnostics.Contracts;

namespace System.Threading.Tasks
{
    /// <summary>
    /// Used as part of <see cref="TaskFactoryEx"/>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal class ProgressNotifier<T> : IProgressNotifier<T>
    {
        private readonly SynchronizationContext _current = SynchronizationContext.Current;

        public ProgressNotifier()
        {
            this.CancellationToken = new CancellationToken();
        }

        public ProgressNotifier(CancellationToken cancellationToken)
        {
            Contract.Requires<ArgumentNullException>(cancellationToken != null, "cancellationToken");
            this.CancellationToken = cancellationToken;
        }

        public Action<T, int> ProgressHandler { get; set; }

        public void Notify(T chunk, int progressPercentage)
        {
            if (ProgressHandler != null)
            {
                if (this._current != null)
                {
                    this._current.Post(_ => ProgressHandler(chunk, progressPercentage), null);
                }
                else
                    ProgressHandler(chunk, progressPercentage);
            }
        }

        public CancellationToken CancellationToken { get; private set; }
    }

    internal class ProgressNotifier : IProgressNotifier
    {
        private readonly SynchronizationContext _current = SynchronizationContext.Current;

        public ProgressNotifier()
        {
            this.CancellationToken = new CancellationToken();
        }

        public ProgressNotifier(CancellationToken cancellationToken)
        {
            Contract.Requires<ArgumentNullException>(cancellationToken != null, "cancellationToken");
            this.CancellationToken = cancellationToken;
        }

        public Action<int> ProgressHandler { get; set; }

        public void Notify(int progressPercentage)
        {
            if (ProgressHandler != null)
            {
                if (this._current != null)
                {
                    this._current.Post(_ => ProgressHandler(progressPercentage), null);
                }
                else
                    ProgressHandler(progressPercentage);
            }
        }

        public CancellationToken CancellationToken { get; private set; }
    }
}